package be.rivendale.ghetto;

import be.rivendale.material.Color;
import be.rivendale.mathematics.Vector;
import org.apache.commons.lang.Validate;

/**
 * Represents a voxel.
 * A voxel does not have any information about it's position in 3D space. This information is implicitly defined by it's
 * index in the 3D voxel grid (just like a pixel does not contain information about it's position on the screen).
 * A voxel has a color and a normal.
 */
public class Voxel {
	/**
	 * The color of this voxel.
	 */
	private Color color;

	/**
	 * The normalized normal of this voxel.
	 * This can be used in shading for example.
	 */
	private Vector normal;

	/**
	 * Creates a new voxel.
	 * @param color The color of the voxel to create.
	 * @param normal The normal of the voxel to create. This normal should be normalized.
	 */
	public Voxel(Color color, Vector normal) {
		this.color = color;
		this.normal = normal;
		validateVoxel();
	}

	/**
	 * Validates this voxel.
	 * If a voxel is instantiated with the wrong parameters an exception is thrown
	 * Wrong parameters are that it doesn't make sense to define a voxel this way, or it will cause corruption
	 * later in the application.
	 */
	private void validateVoxel() {
		Validate.notNull(color, "The color of a voxel is required");
		Validate.notNull(normal, "The normal of a voxel is required");
		Validate.isTrue(normal.isNormalized(), "The normal of a voxel must be normalized");
	}

	/**
	 * Retrieves the color of this voxel.
	 * @return The color of this voxel.
	 */
	public Color getColor() {
		return color;
	}

	/**
	 * Retrieves the normal of this voxel.
	 * @return The normal of this voxel.
	 */
	public Vector getNormal() {
		return normal;
	}
}
